import React, { Component, createRef } from 'react';
import css from './index.module.css';
import { connect } from 'react-redux';
import { updateScreenValue, reset, updateErrorTip } from '../../../redux/action/calculator';
import Header from './Header';
import { Button, Tour } from 'antd';
import { Fragment } from 'react';

class Calculator extends Component {
  btnList = ['←', 'C', '( )', '÷', '7', '8', '9', '×', '4', '5', '6', '-', '1', '2', '3', '+', '.', '0', '='];
  operatorBtnList = ['+', '-', '×', '÷'];
  steps = [
    {
      title: '算式输入区',
      description: '其中"←"是清除最后一位，"C"是清空显示。',
      target: () => this.btnWrapRef.current
    },
    {
      title: '屏幕显示区',
      description: '显示输入的算式及结果。',
      target: () => this.screenRef.current
    },
    {
      title: '算式错误提示区',
      description: '当输入的算式非法时，就会显示错误信息。',
      target: () => this.headerRef.current
    }
  ];
  headerRef = createRef();
  screenRef = createRef();
  btnWrapRef = createRef();
  state = {
    isFirstCilck: true,
    screenValue: '0',
    isOpenTour: false
  };

  btnClick = e => {
    const { update, reset } = this.props;
    const clickText = e.target.innerText;
    if (clickText === '( )') {
      this.addBracket();
      return;
    }
    if (this.IsContinuousOperator(clickText)) {
      update(this.props.screenValue.substring(0, this.props.screenValue.length - 1) + clickText);
      //注意，提交完action并执行reducer后，立马打印拿不到最新值，只能拿到旧值。并且renderr是在这个打印之后，能拿到最新值。
      // console.log('props', this.props.screenValue);
      this.setState({ isFirstCilck: false });
      return;
    }
    if (clickText === '=') {
      update(this.getResult());
      return;
    }
    if (clickText === '←') {
      if (this.props.screenValue.length <= 1) {
        reset();
        this.setState({ isFirstCilck: true });
      } else {
        update(this.props.screenValue.substring(0, this.props.screenValue.length - 1));
        this.setState({ isFirstCilck: false });
      }
      return;
    }
    if (clickText === 'C') {
      reset();
      this.setState({ isFirstCilck: true });
      return;
    }
    update(this.state.isFirstCilck ? clickText : this.props.screenValue + clickText);
    this.setState({ isFirstCilck: false });
  };
  addBracket = () => {
    const { screenValue, update } = this.props;
    const hasLeftBracket = screenValue.includes('(');
    const hasRightBracket = screenValue.includes(')');

    if ((!hasLeftBracket && !hasRightBracket) || hasRightBracket) update(screenValue + '(');
    if (hasLeftBracket) update(screenValue + ')');
    // console.log('括号功能暂未开发');
  };
  IsContinuousOperator = clickText => {
    const clickTextIsOperator = this.operatorBtnList.filter(text => text === clickText).length !== 0;
    const lastText = this.props.screenValue.slice(-1);
    const lastTextIsOperator = this.operatorBtnList.filter(text => text === lastText).length !== 0;
    return clickTextIsOperator && lastTextIsOperator;
  };
  getResult = () => {
    const replaceValue = this.props.screenValue.replace('÷', '/').replace('×', '*');
    let result = '';
    try {
      // eslint-disable-next-line
      result = String(eval(replaceValue));
      if (result === 'Infinity') {
        this.props.errorTip('0不能作为被除数');
        return this.props.screenValue;
      }
    } catch (error) {
      console.log(error);
      this.props.errorTip('算式语法错误');
      return this.props.screenValue;
    }
    return result;
  };
  render() {
    // console.log('render', this.props.screenValue);
    return (
      <Fragment>
        <Button type='primary' onClick={() => this.setState({ isOpenTour: true })} style={{ marginBottom: '12px' }}>
          开始引导
        </Button>
        <div className={css.container}>
          <h2 ref={this.headerRef} className={css.header}>
            <Header errorTip={this.props.errTip} />
          </h2>
          <div ref={this.screenRef} className={css.screen}>
            {this.props.screenValue}
          </div>
          <div ref={this.btnWrapRef} className={css.btnWrap}>
            {this.btnList.map(text => (
              <div key={text} className={text !== '=' ? css.btn : css.equalBtn} onClick={this.btnClick}>
                {text}
              </div>
            ))}
          </div>
          <Tour open={this.state.isOpenTour} onClose={() => this.setState({ isOpenTour: false })} steps={this.steps} />
        </div>
      </Fragment>
    );
  }
}

const mapStateToProps = state => ({ screenValue: state.calculator.screenValue, errTip: state.calculator.errorTip });

const mapDispatchToProps = dispatch => ({
  update: data => dispatch(updateScreenValue(data)),
  reset: data => dispatch(reset(data)),
  errorTip: data => dispatch(updateErrorTip(data))
});
// mapDispatchToProps可直接简写为一个对象：
// {
//   update: updateScreenValue,
//   reset: reset,
//   errorTip: updateErrorTip
// }

export default connect(mapStateToProps, mapDispatchToProps)(Calculator);
